/*
 * ManagerBean.java
 * Session Bean Staless utilizzato per gestire e memorizzare gli Entity Bean.
 */

package ejb;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;


/**
 * La classe ManagerBean rappresenta la session bean 
 * utilizzata per gestire e memorizzare gli entity bean
 * Questa implementa tutti i metodi per la gestione
 * degli entity bean.
 * @author Rosario Salone
 */

@Stateless
public class ManagerBean implements ManagerLocal {
    @PersistenceContext
    private EntityManager em;
    
    /**
     * Memorizza L'object item, passato come parametro, sul database in base al tipo di entity bean,
     * Il metodo verifica il tipo di oggetto e lo inserisce sul db
     * @param item l'oggetto da salvare
     */
    @Override
    public boolean salva(Object item){
        String tipo=item.getClass().toString();
        
        if (tipo.equals("class ejb.Utente")){
            Utente tmp=(Utente)item;
            Utente utente;
            utente=trovaUtente(tmp.getEmail());
            if (utente!=null) return false;
            em.persist((Utente)item);
            return true;
        }
      
        /*if (tipo.equals("class Distanza")){
            em.persist((Distanza)item);
        }
        Non implementato perchè non necessario, il database viene riempito a mano 
        */   
      
        if (tipo.equals("class ejb.Prenotazione")){
            Prenotazione tmp2=(Prenotazione)item;
            Prenotazione prenotazione;
            prenotazione=trovaPrenotazione(tmp2.getPrenotazionePK());
            if (prenotazione!=null) return false;
            em.persist(tmp2);
            return true;
        }
      
        if (tipo.equals("class ejb.Evento")){
            //Evento tmp3=(Evento)item;
            //Evento evento;
            //evento=trovaEvento(tmp3.getCod());
            // if (evento!=null) return false;
            em.persist((Evento)item);
            return true;   
        }
        
        if (tipo.equals("class ejb.Viaggio")){
            Viaggio tmp4=(Viaggio)item;
            Viaggio viaggio;
            viaggio=trovaViaggio(tmp4.getCod());
            if (viaggio!=null) return false;
            em.persist((Viaggio)item);
            return true;
        }
        
       if (tipo.equals("class ejb.Distanza")){
            
            em.persist((Distanza)item);
            return true;
        }

        
        return false;
    }
    
    /**
     * Ricerca e restituisce un utente in base all'indirizzo email di registrazione
     * @param email l'email dell'utente
     * @return utente
     */
    @Override
    public Utente trovaUtente(String email){
        Utente utente=null;
        utente= em.find(Utente.class, email);
        return utente;
    }
    
    /**
     * Ricerca e restituisce una prenotazione in base alla chiave primaria costruita
     * attraverso il codice evento e l'email di registrazione dell'utente.
     * @param prenotazionePk la chiave della prenotazione (codEvento, mailUtente)
     * @return prenotazione
     */
    @Override
    public Prenotazione trovaPrenotazione(PrenotazionePK prenotazionePK){
         Prenotazione prenotazione;
         prenotazione=em.find(Prenotazione.class,prenotazionePK);
         return prenotazione;
    }   
   
    /**
     * Ricerca e restituisce la tipologia di viaggio in base al codice di registrazione
     * @param cod codice del viaggio
     * @return viaggio
     */
    @Override
    public Viaggio trovaViaggio(int cod){
        Viaggio viaggio;
        viaggio=em.find(Viaggio.class,cod);
        return viaggio;
    }   
    
    /**
     * Ricerca e restituisce la distanza che separa due città in base alla chiave primaria costruita 
     * attraverso la città di partenza, di destinazione e la tipologia di trasporto.
     * @param distanzaPk la chiave della distanta (cittàPartenza, cittaArrivo, codViaggio)
     * @return distanza
     */
    @Override
    public Distanza trovaDistanza(DistanzaPK distanzaPK){
        Distanza distanza;
        distanza=em.find(Distanza.class,distanzaPK);
        return distanza;
    }
    
    /**
     * Ricerca tutti gli eventi e li restituisce in una lista
     * @return list
     */
    @Override
    public List trovaEvento(){
        
        //List a = null;
        Query query = em.createQuery("SELECT e FROM Evento e order by e.nome");
        
        return query.getResultList();
        //return a;
    }
    
    /**
     * Ricerca e restituisce un evento in base al codice di registrazione
     * @param cod il codice dell'evento
     * @return evento
     */
    @Override
    public Evento trovaEvento(int cod) {
        Evento ev;
        ev=em.find(Evento.class,cod);
        return ev;
    }
    
    /**
     * Rimuove un utente in base all'indirizzo email di registrazione se presente nel database
     * @param email email dell'utente da rimuovere
     * @return true se l'utente è stato trovato ed eliminato, false alrimenti
     */
    @Override
    public boolean rimuoviUtente(String email){
    
        Utente utente=trovaUtente(email);
        
        if (utente==null) return false;
        em.remove(utente);
        return true;
    }
    
    /**
     * Ricerca e aggiorna le informazioni di un determinato utente passato come parametro
     * @param utente utente da aggiornare
     * @return true se è andato tutto a buon fine, false altrimenti
     */
    @Override
    public boolean aggiornaUtente(Utente tmp){
    
        Utente utente=trovaUtente(tmp.getEmail());
        if (utente !=null){
            utente.setCitta(tmp.getCitta());
            utente.setNome(tmp.getNome());
            utente.setCognome(tmp.getCognome());
            utente.setCodFiscale(tmp.getCodFiscale());
            utente.setTelefono(tmp.getTelefono());
            utente.setPassword(tmp.getPassword());
            utente.setIndirizzo(tmp.getIndirizzo());
            rimuoviUtente(tmp.getEmail());
            salva(utente);
            //if (utente==null) return false;
            // em.refresh(utente);
            return true;
        }
        return false;
    }

    
     /**
     * Rende persistente un oggetto passato come parametro
     * @param object oggetto da rendere persistente
     */
    @Override
    public void persist(Object object) {
        em.persist(object);
        
    }

    @Override
    public List findAllCategories() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void salvaEvento(Evento ev) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean salvaEvento(Object item) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
    
      /**
     * Trova tutte le prenotazioni di un utente e li elimina
     * dal db
     * @param mail chiave utente
     */

    @Override
    public List trovaEventoUtente(String mail) {
        List eventi= this.trovaEvento();
        
        for(int i=0; i<eventi.size(); i++){
            Evento e= (Evento) eventi.get(i);
            PrenotazionePK pk= new PrenotazionePK(e.getCod(), mail);
            Prenotazione p= this.trovaPrenotazione(pk);
            if(p==null){
                eventi.remove(i);
            }
        }
        return eventi;
    }

    
     /**
     * Trova una prenotazione e la elimina
     * dal db
     * @param prenotazionePk chiave della prenotazione
     */

    @Override
    public boolean removePrenotazione(PrenotazionePK pk) {
        Prenotazione p= this.trovaPrenotazione(pk);
        if (p==null) return false;
        em.remove(p);        
        return true;
    }

    @Override
    public List getViaggi() {
             
        //List a = null;
        Query query = em.createQuery("SELECT v FROM Viaggio v");
 
        return query.getResultList();
        //return a;

    }

    @Override
    public boolean salvaDistanzaPk(DistanzaPK dpk) {        
        Distanza d = new Distanza (dpk);
        d.setDistanza(200);
        d.setPrezzo(40);
        return this.salva(d);
    
    }

    @Override
    public List trovaEventoLuogo(String luogo) {
             
        //List a = null;
        Query query = em.createQuery("SELECT e FROM Evento e where e.luogo ='"+luogo+"' order by e.nome");
 
        return query.getResultList();
        //return a;

    }

    @Override
    public List trovaEventoData(String data) {
             
        //List a = null;
        Query query = em.createQuery("SELECT e FROM Evento e where e.data ='"+data+"' order by e.nome");
 
        return query.getResultList();
        //return a;


    }

    @Override
    public List trovaEventoTipo(String tipo) {
             
        //List a = null;
        Query query = em.createQuery("SELECT e FROM Evento e where e.tipo ='"+tipo+"'");
 
        return query.getResultList();
        //return a;


    }

    @Override
    public List trovaEventoNome(String nome) {
             
                       //List a = null;
        Query query = em.createQuery("SELECT e FROM Evento e where e.nome ='"+nome+"' order by e.nome");
 
        return query.getResultList();
        //return a;


    }

    @Override
    public List orderByDate() {
        Query query = em.createQuery("select dataevento from APP.EVENTO group by dataevento");
        List <Date> dates=query.getResultList();
        Collections.sort(dates);
        Query query2 = em.createQuery("select * from APP.EVENTO");
        List events = query2.getResultList();
        Evento[] e = new Evento[events.size()];
        Evento[] dates2 = new Evento[events.size()];
        String s="21/12/07";
        DateFormat df = new SimpleDateFormat ("dd/MM/yy");
        df.setLenient (false);
        Date d;
        try {
            d = df.parse (s);
        } catch (ParseException ex) {
            Logger.getLogger(ManagerBean.class.getName()).log(Level.SEVERE, null, ex);
        }

        
        //List list = Arrays.asList(numbers);
        return null;
    }

    @Override
    public int getCountEvent() {
        Query query = em.createQuery("select max(e.cod) from Evento e");
        List ev = query.getResultList();
        if(ev.isEmpty() || ev==null) {
            return 0;
        }
        else{
        try{
        int num= Integer.parseInt(ev.get(0)+"");
        return num;
        }
        catch(Exception e){
            return 0;
        }
        }
    }     
}
